package com.softWang.file.util.ftp;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.*;

/**
 * author: admin
 * date: 2020/7/8
 * description:
 */
@Component
public class FTPUtils {
    private Logger log = LoggerFactory.getLogger(FTPUtils.class);

    private FTPClientPool ftpClientPool;
    @Autowired
    private FtpPoolConfig ftpPoolConfig;

    public void setFtpClientPool(FTPClientPool ftpClientPool) {
        this.ftpClientPool = ftpClientPool;
    }

    // 下载的文件目录
    private String DOWNLOAD_DIR;


    @PostConstruct
    public boolean init() {
        ftpPoolConfig.setMinEvictableIdleTimeMillis(120000);
        FTPClientFactory factory = new FTPClientFactory(ftpPoolConfig);
        try {
            ftpClientPool = new FTPClientPool(factory);
        } catch (Exception e) {
            log.error("ftp连接池初始化失败");
            return false;
        }
        return true;
    }


    /**
     * 功能：上传文件附件到文件服务器
     *
     * @param buffIn:上传文件流
     * @param fileName：保存文件名称
     * @return
     * @throws IOException
     */
    public String uploadToFtp(InputStream buffIn, String fileName, String remoteDir){
        String returnValue = "";
        FTPClient ftpClient = null;
        // 上传文件
        try {
            ftpClient = ftpClientPool.borrowObject();
            if (remoteDir!= null && !remoteDir.equals("")) {
                if (!existDirectory(remoteDir, ftpClient)) {
                    this.createDir(remoteDir, ftpClient);
                }
                ftpClient.changeWorkingDirectory(remoteDir);
            }
            // 上传文件到ftp
            boolean flag = ftpClient.storeFile(fileName, buffIn);
            if (flag) {
                returnValue = File.separator + remoteDir + fileName;
            }
            // 输出操作结果信息
            if (flag) {
                log.info("ftp上传成功!");
            } else {
                log.info("ftp上传失败!");
            }
        } catch(Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (buffIn != null) {
                    buffIn.close();
                }
            } catch (Exception e) {
                log.error("ftp关闭输入流时失败！", e);
            }finally {
                try {
                    ftpClientPool.returnObject(ftpClient);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return returnValue;
    }


    /**
     * 下载byte文件
     *
     * @param filename
     * @param remoteDir
     * @return
     * @throws IOException
     */
    public byte[] downloadFileByByteArray(String filename, String remoteDir) {
        FTPClient ftpClient = null;
        InputStream in = null;
        byte[] data=null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            ftpClient.changeWorkingDirectory(remoteDir);
            // ftp文件获取文件
            in = ftpClient.retrieveFileStream(filename);
            data = toByteArray(in);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage(), e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                    ftpClient.completePendingCommand();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        ftpClientPool.returnObject(ftpClient);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    return data;

    }

    /**
     * 删除文件
     *
     * @param remoteDir：要删除文件所在目录
     * @param fileName：要删除的文件
     */
    public void deleteFile(String remoteDir, String fileName) throws IOException {
        FTPClient ftpClient = null;
        try {
            ftpClient = ftpClientPool.borrowObject();
            ftpClient.changeWorkingDirectory(remoteDir);
            boolean isSuccess = ftpClient.deleteFile(fileName);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ftpClientPool.returnObject(ftpClient);
        }
    }


    /**
     * 功能：关闭连接
     */
    public void closeConnect(FTPClient ftpClient) {
        try {
            if (ftpClient != null) {
                ftpClient.logout();
                ftpClient.disconnect();
            }
        } catch (Exception e) {
            log.error("ftp连接关闭失败！", e);
        }
    }

    // Check the path is exist; exist return true, else false.
    public boolean existDirectory(String path, FTPClient ftpClient) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpClient.listFiles(path);
        for (FTPFile ftpFile : ftpFileArr) {
            if (ftpFile.isDirectory()
                    && ftpFile.getName().equalsIgnoreCase(path)) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    /**
     * 创建FTP文件夹目录
     *
     * @param pathName
     * @return
     * @throws IOException
     */
    public boolean createDirectory(String pathName, FTPClient ftpClient) throws IOException {
        boolean isSuccess = false;
        try {
            isSuccess = ftpClient.makeDirectory(pathName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isSuccess;
    }

    /**
     * 创建多层目录
     *
     * @param remote
     * @throws UnsupportedEncodingException
     * @throws IOException
     */
    public void createDir(String remote, FTPClient ftpClient) throws UnsupportedEncodingException, IOException {
        String directory = remote;
        if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(directory)) {
            // 如果远程目录不存在，则递归创建远程服务器目录
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf("/", start);
            while (true) {
                String subDirectory = new String(remote.substring(start, end));
                if (!ftpClient.changeWorkingDirectory(subDirectory)) {
                    if (ftpClient.makeDirectory(subDirectory)) {
                        ftpClient.changeWorkingDirectory(subDirectory);
                    } else {
                        System.out.println("创建目录失败");
                    }
                }
                start = end + 1;
                end = directory.indexOf("/", start);
                // 检查所有目录是否创建完毕
                if (end <= start) {
                    break;
                }
            }
        }
    }

    public byte[] toByteArray(InputStream input) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[2048];
        int n = 0;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        byte[] data = output.toByteArray();
        if (null != input) {
            input.close();
        }
        if (null != output) {
            output.close();
        }
        return data;
    }

    /**
     * 带点的
     *
     * @param fileName
     * @return
     */
    public static String getExtention(String fileName) {
        int pos = fileName.lastIndexOf(".");
        return fileName.substring(pos);
    }

    /**
     * 不带点
     *
     * @param fileName
     * @return
     */
    public static String getNoPointExtention(String fileName) {
        int pos = fileName.lastIndexOf(".");
        return fileName.substring(pos + 1);
    }


    public static void main(String[] args) throws Exception {
        try {
            FTPClient ftpClient = new FTPClient();
            ftpClient.connect("192.168.9.195", 21);
            ftpClient.login("sdkj", "sdkj7824310");
            ftpClient.changeWorkingDirectory("/access/2020/07/16/15");
            ftpClient.deleteFile("592b6cd490304f17a2c47e74101349c1.jpg");
        } catch (FTPConnectionClosedException ex) {
            throw ex;
        }
    }
}
